package com.sike.config;

import com.sike.utils.ValidCodeFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
    private final ValidCodeFilter validCodeFilter;

    public WebSecurityConfig(ValidCodeFilter validCodeFilter) {
        this.validCodeFilter = validCodeFilter;
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        UserDetails user1 = User.withUsername("admin").password(passwordEncoder().encode("123456")).roles("role1", "role2", "role3").build();
        UserDetails user2 = User.withUsername("user1").password(passwordEncoder().encode("123456")).roles("role1").build();
        UserDetails user3 = User.withUsername("user2").password(passwordEncoder().encode("123456")).roles("role2").build();
        UserDetails user4 = User.withUsername("user3").password(passwordEncoder().encode("123456")).roles("role3").build();
        manager.createUser(user1);
        manager.createUser(user2);
        manager.createUser(user3);
        manager.createUser(user4);
        return manager;
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().requestMatchers("/js/", "/css/", "/images/**");
    }

    @Bean
    SecurityFilterChain filterChain( HttpSecurity httpSecurity) throws Exception {
        httpSecurity.addFilterBefore(validCodeFilter, UsernamePasswordAuthenticationFilter.class);

        httpSecurity.exceptionHandling().accessDeniedPage("/errorRole");

        httpSecurity.authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/index", "/validcode","/redis","/random/paynum").permitAll()
                .requestMatchers("/menu1/**").hasRole("role1")
                .requestMatchers("/menu2/**").hasRole("role2")
                .requestMatchers("/menu3/**").hasRole("role3")
                .anyRequest().authenticated());
        httpSecurity.formLogin()
                .loginPage("/toLogin")
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")

/*                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.setContentType("application/json;charset=utf-8");
                        PrintWriter out = response.getWriter();
                        String json = "{\"status\":\"ok\",\"msg\":\"登录成功\"}";
                        out.write(json);
                    }
                })*/
/*                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                        response.setContentType("application/json;charset=utf-8");
                        PrintWriter out = response.getWriter();
                        String json = "{\"status\":\"error\",\"msg\":\"登录失败\"}";
                        out.write(json);
                    }
                })*/
                .failureUrl("/toLogin/error")
                .permitAll();
/*        httpSecurity.logout().logoutSuccessHandler(new LogoutSuccessHandler() {
            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                response.setContentType("application/json;charset=utf-8");
                PrintWriter out = response.getWriter();
                String json = "{\"status\":\"ok\",\"msg\":\"退出成功\"}";
                out.write(json);
            }
        });*/

        //开启注销
        httpSecurity.logout().logoutSuccessUrl("/index");
        // 关闭csrf
        httpSecurity.csrf().disable();
        // 启用记住我
        httpSecurity.rememberMe();
        return httpSecurity.build();
    }

}
